<template>
<!-- 多条件查询 -->
  <div style="width: 95%;margin: auto;">
        <!-- 
        :inline :把el-form-item 设置 行内元素
         -->
        <el-form :inline="true" :model="user" class="demo-form-inline">
          <el-form-item style="width: 100px;">
            <el-input v-model="user.username" placeholder="请输入姓名" clearable />
          </el-form-item>
          <el-form-item style="width: 100px;">
            <el-select v-model="user.type" placeholder="请选择类型" clearable >
              <el-option label="管理员" value="1" />
              <el-option label="业主用户" value="2" />
            </el-select>
          </el-form-item>
          <el-form-item style="width: 180px;">
            <el-input v-model="user.remarks" placeholder="备注" clearable />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="getUsersByConditions(1)">查询</el-button>
          </el-form-item>
        </el-form>
  </div>
  <!-- 添加和删除 -->
  <div style="width: 95%;margin: auto;">
        <el-button type="primary" :icon="Plus" @click="addUserBtn">添加用户</el-button>
        <el-button type="primary" :icon="Delete"  @click="">批量删除</el-button>
  </div>
<!-- 用户添加和修改共用的弹窗 -->
 <div>
      <!-- 新增用户和修改对话框 -->
      <el-dialog v-model="dialogForUser.visible" :title="dialogForUser.title" width="25%" draggable>
        <!-- 新增用户表单 -->
        <el-form :inline="true" :model="dialogForUser.user" class="demo-form-inline">
            <el-form-item >
                <el-input v-model="dialogForUser.user.username" placeholder="请输入用户名" clearable  style="width: 200px;height: 35px;"/>
            </el-form-item>
            <!-- 显示上传图片 -->
             <div  style="position:  absolute;top: 50px;left: 240px; width: 30%; height: 100px;background-color:#FAFAFA ;text-align: center;border-radius: 5px;" >
                <el-image @click="showUpLoadImgPage" :src="dialogForUser.user.imgPath"  style="border-radius: 5%;width: 100%;"/>
                <!-- <el-button @click="showUploadImageDialog()" style="width: 90px;height: 10px;background-color: #FAFAFA;line-height: 10px;font-size: 12px;">添加图片</el-button> -->
             </div>
            
            <el-select v-model="dialogForUser.user.type"  placeholder="选择用户类型" clearable style="width: 200px;" >
                <!-- label：表示显示文本内容  value:表示提交值 -->
            <el-option label="管理员" :value="1" />
            <el-option label="业主用户" :value="2" />
          </el-select>
            <el-input v-model="dialogForUser.user.remarks" :rows="2" type="textarea" placeholder="输入备注信息" style="width: 340px;margin-top: 20px;"/>
            <el-form-item style="margin-top: 20px;">
              <el-button type="primary" @click="addUser">{{dialogForUser.btnText}}</el-button>
              <el-button type="primary" @click="">重置</el-button>
            </el-form-item>
          </el-form>
      </el-dialog>
</div>
<!-- 用于上传头像的表单 -->
 <div>
    <el-dialog v-model="dialogUpLoadImg.visible" title="文件上传" width="30%" draggable>
        <el-upload
            :action="dialogUpLoadImg.uploadUrl"
            list-type="picture-card"
            :file-list="dialogUpLoadImg.fileList"
            :limit="dialogUpLoadImg.limit"
            :auto-upload="dialogUpLoadImg.autoUpload"
            :on-change="handlerImage">
            <el-icon><Plus /></el-icon>
        </el-upload>
        <!-- 添加上传按钮 -->
        <el-form-item style="margin-top: 10px;margin-left: 320px;">
            <el-button type="primary" @click="uploadHandler()">上传</el-button>
          </el-form-item>
    </el-dialog>
</div>

 <!-- 分配角色的弹窗 -->
<div>
   <el-dialog v-model="rolesDialog.visible" title="分配角色" width="40%" draggable>
     <el-checkbox
    v-model="rolesDialog.checkAll"
    :indeterminate="rolesDialog.isIndeterminate"
    @change="handleCheckAllChange"
  >
    Check all
  </el-checkbox>
  <el-checkbox-group
    v-model="rolesDialog.checkedRoles"
    @change="handleCheckedRolesChange"
  >
    <el-checkbox v-for="role in rolesDialog.roles" :key="role.rid" :label="role" :value="role" >
      {{ role.rname }}
    </el-checkbox>
  </el-checkbox-group>
  <!-- 弹窗中添加提交按钮 -->
    <el-button link type="primary" size="small" @click="submitChageRoles">
          确认修改
        </el-button>
        <el-button link type="danger" size="small" @click="resetRoleDialog">重置</el-button>
   </el-dialog>
</div>
   <!--  table -->
  <el-table :data="users" 
  style="width: 100%"
  row-key="id"
  @selection-change="">
    <el-table-column type="selection" width="55" />
    <el-table-column prop="id" label="id" width="150" />
    <el-table-column prop="username" label="用户名" width="200" />
    <el-table-column prop="password" label="密码" width="120" />
    <el-table-column prop="type" label="类型" width="120">
       <template #default ="scope">
         <el-tag v-if="scope.row.type == 1" type="primary">管理员</el-tag>
            <el-tag v-else type="danger">业主</el-tag>
      </template>
    </el-table-column>
    <el-table-column prop="roles" label="角色" width="120">
       <template #default ="scope">
        <div v-for="(role,index) in scope.row.roles">
          <el-tag v-if="role.rname == '管理员'" type="primary">{{role.rname}}</el-tag>
          <el-tag v-else-if="role.rname == '业主用户'" type="success">{{role.rname}}</el-tag>
          <el-tag v-else type="danger">{{role.rname}}</el-tag>
        </div>
        
      </template>
    </el-table-column>
    <el-table-column prop="remarks" label="备注" width="120" />
    <!-- <el-table-column prop="address" label="Address" width="600" />
    <el-table-column prop="zip" label="Zip" width="120" /> -->
    <el-table-column fixed="right" label="操作" min-width="120">
      <template #default = "scope">
        <el-button link type="primary" size="small" @click="editUserBtn(scope.row)">
          编辑
        </el-button>
        <el-button link type="danger" size="small">删除</el-button>
        <el-button link type="warning" size="small" @click="rolesBtn(scope.row)">分配角色</el-button>
      </template>
    </el-table-column>
  </el-table>
  <!-- 分页插件 -->
    <div style="width: 95%;margin: 10px auto;">
        <el-pagination background layout="prev, pager, next" 
        v-model:page-size="page.pageSize"
        v-model:current-page="page.currentPage"
        :total="page.total" 
        @current-change="changePage"/>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, ref,reactive } from 'vue';
import { userapi } from '@/api/userapi';
import { pa } from 'element-plus/es/locales.mjs';
import {Delete,Edit,Plus} from '@element-plus/icons-vue'
import type { CheckboxValueType } from 'element-plus'
import { roleApi } from '@/api/role-api';
import type { UploadFile } from 'element-plus'
import { ElMessage } from 'element-plus';
interface User{
    id:number| null,
    username:string,
    password:string,
    type:number |null,
    remarks:string,
    imgPath:string,
    roles:Role[]
}
interface Role{
  rid:number,
  rname:string,
  remark:string
}
const blankUser = ref<User>({
    id:null,
    username:'',
    password:'',
    type:null,
    remarks:'',
    imgPath:'',
    roles:[]
})
//创建一个添加用户的弹窗
const dialogForUser= ref<{visible:boolean, user:User, btnText:string,title:string}>({
  visible:false,
  user:{
    id:null,
    username:'',
    password:'',
    type:null,
    remarks:'',
    imgPath:'',
    roles:[]
  },
  btnText:'',
  title:''
})
//添加用户的btn对应的事件
const addUserBtn = () =>{
  //弹窗可见
  dialogForUser.value.visible = true;
  //修改弹窗名字
  dialogForUser.value.title='添加用户';
  //修改btn文本
  dialogForUser.value.btnText='添加';
  //更新dialog 中user的数据，避免上次填写的数据残留
  dialogForUser.value.user = createBlankUser();
}

const dialogUpLoadImg = ref<{visible:boolean, uploadUrl:string,fileList:string[],limit:number,autoUpload:boolean,file:any}>({
  visible:false, //隐藏对话框
  uploadUrl:"",
  fileList:[], //保存所有上传文件集合
  limit:1,//控制文件上传个数
  autoUpload:false,
  file:null
})


//dialog 中添加用户的操作分为两部分 一部分是图片上传， 一部分是发送请求 
//图片上传 - 图片上传要新增一个弹窗
const showUpLoadImgPage = () => {
  //打开弹窗
  dialogUpLoadImg.value.visible = true;
}
//选中文件时触发函数
    const handlerImage = (file:UploadFile) => {
        dialogUpLoadImg.value.file = file.raw;
    }
//实现文件上传函数
    const uploadHandler = async () => {
        //文件上传详细步骤
        //1.创建FormData对象
        let formData = new FormData();
        //2.设置上传对象对象
        
        formData.append("file",dialogUpLoadImg.value.file)
        console.log(formData.get("file"));
        
        
        //3.设置上传类型
        let contentType = {"ContentType":"multipart/form-data"}
        formData.append("headers",contentType);
        //4.发送请求实现文件上传
        let res = await userapi.uploadImg(formData)
        // console.log(res.data);
        if(res.data.success){
            //把上传文件保存到表单imgPath中
            dialogForUser.value.user.imgPath= res.data.data; //http://localhost:80/xxxx.png
            //显示提示信息
            ElMessage.success("上传成功");
            //关闭文件上传对话框
            dialogUpLoadImg.value.visible = false;
        }
    }
    const resetDialogForUser = () =>{

    }
//定义变量控制文件上传
    // const uploadDialog = reactive({
    //     visible:false, //隐藏对话框
    //     uploadUrl:"",
    //     fileList:[], //保存所有上传文件集合
    //     limit:1,//控制文件上传个数
    //     autoUpload:false,
    //     uploadFile:null,
    // })

    

//页码类型+响应式对象
interface Page{
  currentPage:number,
  pageSize:number,
  total:number,

}
const page = ref<Page>({
  currentPage:1,
  pageSize:5,
  total:0
})
//创建响应式变量 - user数组 用于table中
const users = ref<User[]>([])

//用于条件查询的响应式对象
const user = ref<User>({
    id:null,
    username:'',
    password:'',
    type:null,
    remarks:'',
    imgPath:'',
    roles:[]
})
let userForm:User;
//写条件查询 这是条件查询的参数，不能和翻页用在同一个
//每次查询都是从第一页开始，但是翻页则是由页面提供当前页数
//翻页还是没写好，还要使用浅拷贝 或者深拷贝 避免引用复用的问题
const getUsersByConditions = async (currentPage:number) =>{
  userForm = {...user.value}
  console.log(user.value);
  page.value.currentPage = currentPage;
  // let currentPage = page.value.currentPage;
  // let pageSize = page.value.pageSize;
  let res = await userapi.getUsersByCondition(page.value.currentPage.toString(),page.value.pageSize.toString(),user.value);
  console.log(res);
  //在请求成功后
  if(res.data.success) {
    console.log("查询成功");
    users.value = res.data.data.records;
    page.value.total = res.data.data.total;
    page.value.pageSize = res.data.data.pageSize;
    page.value.currentPage = res.data.data.currentPage;
  }
}
//设定一个翻页的事件
const changePage = async() =>{
  let res = await userapi.getUsersByCondition(page.value.currentPage.toString(),page.value.pageSize.toString(),userForm);
  if(res.data.success) {
    console.log("查询成功");
    users.value = res.data.data.records;
    page.value.total = res.data.data.total;
    page.value.pageSize = res.data.data.pageSize;
    page.value.currentPage = res.data.data.currentPage;
  }
}
//获得所有用户
const getAllUser = async () =>{
  console.log("get all user");
  let currentPage = page.value.currentPage;
  let pageSize = page.value.pageSize;
  let res =  await userapi.getAllUsers(currentPage.toString(),pageSize.toString());
  console.log(res);
  if(res.data.success) {
    users.value = res.data.data.records;
    console.log(users.value);
    page.value.total = res.data.data.total;
    page.value.pageSize = res.data.data.pageSize;
    page.value.currentPage = res.data.data.currentPage;
  }
}

//写一个响应式 roles dialog - 出了一下这些数据，还应该拿到这个用户本身的数据
const rolesDialog = ref<{visible:boolean,checkedRoles:Role[],roles:Role[],checkAll:boolean,isIndeterminate:boolean, user:User}>({
  visible:false,
  roles:[],
  checkedRoles:[],
  checkAll:false,
  isIndeterminate:true,
  user:{
    id:null,
    username:'',
    password:'',
    type:null,
    remarks:'',
    imgPath:'',
    roles:[]
  }
})
//rolesBtn 用于打开roles dialog 并将数据附上去
const rolesBtn = async (user:User) =>{
  //打开dialog
  rolesDialog.value.visible = true;
  //搜索全部的角色数据
  let res = await roleApi.getAll();
  //被选中的角色应该是目前该用户已经有的角色
  rolesDialog.value.checkedRoles = [...user.roles]
  //对用户本身做一个浅拷贝 - 不拷贝用户内部的roles对象数组了
  rolesDialog.value.user = {...user};
  console.log(rolesDialog.value.checkedRoles);
  //console.log(res);
  if(res.data.success) {
    rolesDialog.value.roles = res.data.data;
  }
  console.log(rolesDialog.value.roles);
  
}
//用于设定全选和复选框选定与不选定状态修改的代码
const handleCheckAllChange = (val: CheckboxValueType) => {
  console.log(val);
  rolesDialog.value.checkedRoles = (val ? rolesDialog.value.roles : [])
  rolesDialog.value.isIndeterminate = false
}
//装选定的role的id的变量
let roleIds:Number[] = [];
//选定角色时的改变事件
const handleCheckedRolesChange = (value: CheckboxValueType[]) => {
  //开始修改就将ids清空
  roleIds = [];
  const checkedCount = value.length
  rolesDialog.value.checkAll = (checkedCount === rolesDialog.value.roles.length);
  console.log(checkedCount,rolesDialog.value.roles.length);
  
  rolesDialog.value.isIndeterminate = (checkedCount > 0 && checkedCount < rolesDialog.value.roles.length)
  //对应弹窗中的checkedRoles  
  //console.log(rolesDialog.value.checkedRoles);
  for (let i = 0; i < rolesDialog.value.checkedRoles.length; i++) {
    const roleId = rolesDialog.value.checkedRoles[i].rid;
    roleIds.push(roleId);
  }
  console.log(roleIds);
}
const submitChageRoles = async () => {
  console.log(rolesDialog.value.user);
  console.log(roleIds);
  const userid = rolesDialog.value.user.id;
  if (userid != null) {
    let res = await userapi.modifyUserRoles(roleIds.toString(),userid);
    if(res.data.success) {
      //修改数组后，刷新页面
      getAllUser();
      //关闭弹窗
      rolesDialog.value.visible = false;

    }
  } else {
    console.log("添加失败");
    
  }
}
//重置添加角色的复选框，其实就是重新刷新一下选中的角色框
const resetRoleDialog = () =>{
  rolesDialog.value.checkedRoles = [...rolesDialog.value.user.roles]
}

//修改用户信息的btn
const editUserBtn = (user:User) =>{
//dialog visible
  dialogForUser.value.visible = true;
  dialogForUser.value.btnText = '修改';
  dialogForUser.value.title = '修改信息';
  dialogForUser.value.user = user;
}

const addUser = async () =>{
  let res = await userapi.addUser(dialogForUser.value.user);
  console.log(res);
  
  if(res.data.success) {
    dialogForUser.value.visible = false;
    dialogForUser.value.user = createBlankUser();
    getUsersByConditions(1);
  }
}
//创建空白user 用于每次更新表单
const createBlankUser = (): User => ({
  id: null,
  username: '',
  password: '',
  type: null,
  remarks: '',
  imgPath: '',
  roles: []
})

//角色选择弹窗中提交按钮
onMounted (() =>{
  getUsersByConditions(1);
})

// 测试复选框数据r

</script>